﻿using LD.Host;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;

namespace LD.BC
{
    [Bc(Name = "雷赛DMCE3032", Brand = BrandType.DMCE3032)]
    class DMCE3032 : LTDMC_E3032, IBoardCard
    {
        private string[] sportModes = { "定长运动", "定速运动", "回零运动", "往复运动" };
        private string[] stopModes = { "减速停止", "立即停止" };
        private string[] locationModes = { "相对坐标", "绝对坐标" };
        private string[] directionModes = { "负方向", "正方向" };
        private string[] zeroModes = { "一次回零", "一次回零+反找", "两次回零", "一次回零+EZ", "EZ回零", "一次回零+反找"
        ,"原点锁存","原点+EZ锁存","EZ锁存","原点+反向EZ锁","限位一次回零","限位回零反找","限位两次回零" };
        private string[] speedModes = { "低速回零", "高速回零" };
        private string[] pluseModes = { "脉冲/方向", "脉冲/脉冲" };

        public Dictionary<string, string[]> GetParam()
        {
            Dictionary<string, string[]> param = new Dictionary<string, string[]>
            {
                { "sportModes", sportModes },
                { "stopModes", stopModes },
                { "locationModes", locationModes },
                { "directionModes", directionModes },
                { "zeroModes", zeroModes },
                { "speedModes", speedModes },
                { "pluseModes", pluseModes }
            };
            return param;
        }

        private TaskEx TaskEx = new TaskEx();
        private ushort _bcId;
        public void ClearAlart(ushort axisId)
        {
            //清除总线轴错误码
            Error(nmc_clear_axis_errcode(_bcId, axisId));
            ClearAlart();
        }
        /// <summary>
        /// 清除所有轴
        /// </summary>
        public void ClearAlart()
        {
            //清除总线轴错误码
            Error(nmc_clear_errcode(_bcId, 2));
        }
        public void Closed()
        {
            TaskEx?.Cancel();
            //停止EtherCAT总线运行
            ushort state = 0;
            Error(nmc_stop_etc(_bcId, ref state));
            Error(dmc_board_close());
        }

        public void Connection()
        {
            short num = dmc_board_init();//获取卡数量
            if (num <= 0 || num > 8)
            {
                Log4.Error("板卡初始化失败,未检测到板卡,请检查驱动");
                throw new Exception("板卡初始化失败");
            }
            //设置控制卡工作模式0 表示仿真模式，1 表示 EtherCAT 总线模式
            Error(nmc_set_controller_workmode(_bcId, 1));
            //当总线报掉线报错以后，设置网络拓扑轴是否可以操作
            Error(nmc_set_fieldbus_error_switch(_bcId, 2, 0));
        }

        public void DownAxisParam()
        {
            //下载参数
            foreach (var item in BcFactory.Instance.Config.AxisParam)
            {
                SetAxisParam(item.AxisId, item);

                //打开使能
                SetSevon(item.AxisId, true);
            }
        }

        public AlmModel GetAlm(ushort axisId)
        {
            return new AlmModel();
        }

        public double GetAxisPosition(ushort axis)
        {
            double result = 0;
            Error(dmc_get_position_unit(_bcId, axis, ref result));
            return result;
        }

        public string GetAxisStatus(ushort cardNo, ushort axis)
        {
            var status = dmc_axis_io_status(_bcId, axis);
            string bin2_status = Convert.ToString(status, 2).PadLeft(12, '0');
            return bin2_status;
        }

        public double GetEquiv(ushort cardNo, ushort axis)
        {
            double v = 0;
            Error(dmc_get_equiv(cardNo, axis, ref v));
            return v;
        }

        public bool GetHomeStatus(ushort axis)
        {
            throw new NotImplementedException();
        }

        public int GetIn(int outPos)
        {
            return dmc_read_inbit(_bcId, (ushort)outPos);
        }

        public int GetOut(int outPos)
        {
            return dmc_read_outbit(_bcId, (ushort)outPos);
        }

        public bool IsMoving()
        {
            bool moving = false;
            foreach (var item in BcFactory.Instance.Config.AxisParam)
            {
                int i = item.AxisId;
                moving = dmc_check_done(0, (ushort)i) == 0 ? true : false;
                if (moving)
                    return moving;
            }

            return moving;
        }

        public void LoadConfig(string fileName)
        {
            Error(dmc_download_configfile(_bcId, fileName));
        }

        public void Move(ushort axis, ushort direction)
        {
            if (BCAlertHelper.GetErrorQty) return;
            var moveP = BcFactory.Instance.Config.AxisParam.Where(p => p.AxisId == axis).FirstOrDefault();
            if (moveP == null)
            {
                throw new Exception("轴参数无设置");
            }
            ushort MyCardNo, Myaxis;
            double MyMin_Vel, MyMax_Vel, MyTacc, MyTdec, MyStop_Vel;
            MyCardNo = _bcId;                               //卡号
            Myaxis = axis;                                                  //轴号
            MyMin_Vel = (double)moveP.Min_val;                              //起始速度 200pulse/s
            MyMax_Vel = (double)moveP.Max_val;                              //最大速度 5000pulse/s
            MyTacc = (double)moveP.Tacc;                                    //加速时间 0.01s
            MyTdec = (double)moveP.Tdec;                                    //减速时间 0.01s
            MyStop_Vel = (double)moveP.Stop_val;                            //停止速度 200pulse/s 

            if (BcFactory.Instance.RunModel == StateEnum.手动模式)
                MyMax_Vel = (double)moveP.Manual_val;

            Error(dmc_set_profile_unit(MyCardNo, Myaxis, MyMin_Vel, MyMax_Vel, MyTacc, MyTdec, MyStop_Vel));
            Error(dmc_set_s_profile(MyCardNo, Myaxis, 0, (double)moveP.S_Para));//设置单轴运动速度曲线 
            Error(dmc_vmove(MyCardNo, Myaxis, direction));                   //执行运动
        }

        public void Move_BackZero(ushort axis)
        {
            if (BCAlertHelper.GetErrorQty) return;
            var moveP = BcFactory.Instance.Config.AxisParam.Where(p => p.AxisId == axis).FirstOrDefault();
            if (moveP == null)
            {
                throw new Exception("轴参数无设置");
            }
            ushort MyCardNo, Myaxis, Myorg_logic, Myfilter, Myhome_dir, Mymode, MyEZ_count;
            double Myvel_mode;
            MyCardNo = _bcId;                                       //卡号
            Myaxis = axis;                                          //轴号
            Myorg_logic = 0;                                        //原点信号有效电平为低电平有效
            Myfilter = 0;                                           //保留参数
            Myhome_dir = (ushort)moveP.Zero_dir;                    //回零方向为正向
            Myvel_mode = 1;                                         //回零高低速
            Mymode = (ushort)moveP.Zero_Model;                      //回零方式为一次回零
            MyEZ_count = 0;                                         //保留参数

            double MyMin_Vel, MyMax_Vel, MyTacc, MyTdec, MyStop_Vel;

            MyMin_Vel = moveP.Min_val;                              //起始速度 200pulse/s
            MyMax_Vel = moveP.Zero_val; ;                           //最大速度 5000pulse/s
            MyTacc = moveP.Tacc;                                    //加速时间 0.01s
            MyTdec = moveP.Tdec;                                    //减速时间 0.01s
            MyStop_Vel = moveP.Stop_val;                            //停止速度 200pulse/s

            //设置 0 号轴梯形速度曲线参数
            Error(dmc_set_profile_unit(MyCardNo, Myaxis, MyMin_Vel, MyMax_Vel, MyTacc, MyTdec, MyStop_Vel));
            Error(nmc_set_home_profile(MyCardNo, Myaxis, Mymode, MyMin_Vel, MyMax_Vel, MyTacc, MyTdec, 0));

            //执行回原点运动
            Error(dmc_home_move(MyCardNo, Myaxis));

            WaitAxisComplete(Myaxis);

            //get回零信号
            uint status = dmc_axis_io_status(MyCardNo, Myaxis);
            string bin2_status = Convert.ToString(status, 2).PadLeft(12, '0');
            if (Convert.ToUInt16(bin2_status.Substring(7, 1)) == 1)
            {
                Error(dmc_set_position_unit(MyCardNo, Myaxis, 0));
            }
        }

        public void Move_Location(ushort axis, double location)
        {
            if (BCAlertHelper.GetErrorQty) return;

            var moveP = BcFactory.Instance.Config.AxisParam.Where(p => p.AxisId == axis).FirstOrDefault();
            if (moveP == null)
            {
                throw new Exception("轴参数无设置");
            }
            ushort MyCardNo, Myaxis, Myposi_mode;
            double MyMin_Vel, MyMax_Vel, MyTacc, MyTdec, MyStop_Vel;
            double MyDist;
            MyCardNo = _bcId;                               //卡号
            Myaxis = axis;                                                  //轴号
            MyMin_Vel = (double)moveP.Min_val;                              //起始速度 200pulse/s
            MyMax_Vel = (double)moveP.Max_val;                              //最大速度 5000pulse/s
            MyTacc = (double)moveP.Tacc;                                    //加速时间 0.01s
            MyTdec = (double)moveP.Tdec;                                    //减速时间 0.01s
            MyStop_Vel = (double)moveP.Stop_val;                            //停止速度 200pulse/s 
            MyDist = (double)location;                                      //位移为 6000pulse
            Myposi_mode = 1;                                                //0:相对，1:绝对坐标

            if (BcFactory.Instance.RunModel == StateEnum.手动模式)
                MyMax_Vel = (double)moveP.Manual_val;

            //设置单轴运动速度曲线
            Error(dmc_set_profile_unit(MyCardNo, Myaxis, MyMin_Vel, MyMax_Vel, MyTacc, MyTdec, MyStop_Vel));
            //执行点位运动
            Error(dmc_pmove_unit(MyCardNo, Myaxis, MyDist, Myposi_mode));
        }

        public void Move_Ration(ushort axis, ushort direction, double ration_v)
        {
            if (BCAlertHelper.GetErrorQty) return;
            var moveP = BcFactory.Instance.Config.AxisParam.Where(p => p.AxisId == axis).FirstOrDefault();
            if (moveP == null)
            {
                throw new Exception("轴参数无设置");
            }
            ushort MyCardNo, Myaxis, Myposi_mode;
            double MyMin_Vel, MyMax_Vel, MyTacc, MyTdec, MyStop_Vel;
            double MyDist;
            MyCardNo = _bcId;                               //卡号
            Myaxis = axis;                                                  //轴号
            MyMin_Vel = (double)moveP.Min_val;                              //起始速度 200pulse/s
            MyMax_Vel = (double)moveP.Max_val;                              //最大速度 5000pulse/s
            MyTacc = (double)moveP.Tacc;                                    //加速时间 0.01s
            MyTdec = (double)moveP.Tdec;                                    //减速时间 0.01s
            MyStop_Vel = (double)moveP.Stop_val;                            //停止速度 200pulse/s 
            MyDist = direction == 0 ? -ration_v : ration_v;                 //位移为 6000pulse
            Myposi_mode = 0;                                                //0:相对，1:绝对坐标

            if (BcFactory.Instance.RunModel == StateEnum.手动模式)
                MyMax_Vel = (double)moveP.Manual_val;

            Error(dmc_set_profile_unit(MyCardNo, Myaxis, MyMin_Vel, MyMax_Vel, MyTacc, MyTdec, MyStop_Vel));
            Error(dmc_set_s_profile(MyCardNo, Myaxis, 0, (double)moveP.S_Para));//设置单轴运动速度曲线 
            Error(dmc_pmove_unit(MyCardNo, Myaxis, MyDist, Myposi_mode));    //执行点位运动
        }

        public void Move_Ration(ushort axis, double ration_v)
        {
            if (BCAlertHelper.GetErrorQty) return;
            var moveP = BcFactory.Instance.Config.AxisParam.Where(p => p.AxisId == axis).FirstOrDefault();
            if (moveP == null)
            {
                throw new Exception("轴参数无设置");
            }
            ushort MyCardNo, Myaxis, Myposi_mode;
            double MyMin_Vel, MyMax_Vel, MyTacc, MyTdec, MyStop_Vel;
            double MyDist;
            MyCardNo = _bcId;                                               //卡号
            Myaxis = axis;                                                  //轴号
            MyMin_Vel = (double)moveP.Min_val;                              //起始速度 200pulse/s
            MyMax_Vel = (double)moveP.Max_val;                              //最大速度 5000pulse/s
            MyTacc = (double)moveP.Tacc;                                    //加速时间 0.01s
            MyTdec = (double)moveP.Tdec;                                    //减速时间 0.01s
            MyStop_Vel = (double)moveP.Stop_val;                            //停止速度 200pulse/s 
            MyDist = ration_v;                                              //位移为 6000pulse
            Myposi_mode = 0;                                                //0:相对，1:绝对坐标

            if (BcFactory.Instance.RunModel == StateEnum.手动模式)
                MyMax_Vel = (double)moveP.Manual_val;

            //设置单轴运动速度曲线
            Error(dmc_set_profile_unit(MyCardNo, Myaxis, MyMin_Vel, MyMax_Vel, MyTacc, MyTdec, MyStop_Vel));
            //设置单轴速度曲线 S 段参数值
            Error(dmc_set_s_profile(MyCardNo, Myaxis, 0, (double)moveP.S_Para));
            //执行点位运动
            Error(dmc_pmove_unit(MyCardNo, Myaxis, MyDist, Myposi_mode));
        }

        public int SetAlm(ushort axisId, ushort enable, ushort val)
        {
            throw new Exception("此板卡无此功能");
        }

        public void SetAxisParam(ushort axis, TB_AxisParam model)
        {

        }

        public void SetAxisPosition(ushort axis, double position)
        {
            Error(dmc_set_position_unit(_bcId, axis, position));
        }

        public void SetEquiv(dynamic cardNo, ushort axis, double equiv)
        {
            Error(dmc_set_equiv(cardNo, axis, equiv));
        }

        public void SetOut(ushort outPos, ushort low_high)
        {
            Error(dmc_write_outbit(_bcId, outPos, low_high));
        }

        public void SetSevon(ushort axisId, bool isEnabled)
        {
            //EtherCAT 总线轴的轴号，255 表示使能所有 EtherCAT 轴
            short val = 0;
            if (isEnabled)
                val = nmc_set_axis_enable(_bcId, axisId);
            else
                val = nmc_set_axis_disable(_bcId, axisId);

            Error(val);
        }

        public void SetSevonAll(bool isEnabled)
        {
            foreach (var item in BcFactory.Instance.Config.AxisParam)
            {
                SetSevon(item.AxisId, isEnabled);
            }
        }

        public void SetSoftLimit(ushort cardNo, ushort axis, int n_limit, int p_limit)
        {
            ushort enabled = 1;         //使能状态，0：禁止，1：允许
            ushort source_sel = 0;      //计数器选择，0：指令位置计数器，1：编码器计数器
            ushort sl_action = 0;       //限位停止方式，0：立即停止 1：减速停止
            var val = dmc_set_softlimit(cardNo, axis, enabled, source_sel, sl_action, n_limit, p_limit);
            Error(val);
        }

        public void Start()
        {
            Log4.Info("板卡监控启动");
            TaskEx.Start(Monitor, null);
        }

        public void Stop(ushort axis)
        {
            Error(dmc_stop(_bcId, axis, 1));
        }

        public void StopALL()
        {
            Error(dmc_emg_stop(_bcId));
        }

        public void WaitAxisComplete(ushort axis)
        {
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            while (dmc_check_done(_bcId, axis) == 0 && stopwatch.ElapsedMilliseconds < (30 * 1000))// 判断轴运动状态
            {
                Task.Delay(50).Wait();
            }
            stopwatch.Stop();
        }

        public void WaitAxisComplete()
        {

        }
        #region 私有方法
        private void Monitor(object obj)
        {
            MonitorModel m_Data = new MonitorModel();
            try
            {
                #region IO
                var _in = dmc_read_inport(_bcId, 0);
                var _out = dmc_read_outport(_bcId, 0);
                var bin_in1 = Convert.ToString(_in, 2).PadLeft(16, '0').Reversal().ToList();
                for (int i = 0; i < 16; i++)
                {
                    m_Data.DI.Add(Convert.ToInt32(bin_in1[i].ToString()));
                }

                var bin_out = Convert.ToString(_out, 2).PadLeft(16, '0').Reversal().ToList();
                for (int i = 0; i < 16; i++)
                {
                    m_Data.DO.Add(Convert.ToInt32(bin_out[i].ToString()));
                }
                #endregion

                foreach (var item in BcFactory.Instance.Config.AxisParam)
                {
                    ushort id = item.AxisId;
                    //读取EtherCAT总线轴状态机
                    ushort state = 0;
                    Error(nmc_get_axis_state_machine(_bcId, id, ref state));
                    if (state == 6 || state == 7)
                        Log4.Error($"【{id}轴】错误触发状态or错误状态");
                    //读取总线轴错误码
                    Error(nmc_get_axis_errcode(_bcId, id, ref state));
                    ErrorByEthernet((short)state);

                    #region 轴坐标
                    double pos = GetAxisPosition(id);
                    #endregion

                    #region 轴状态
                    var axisState = dmc_axis_io_status(_bcId, id);
                    var bin_axis = Convert.ToString(axisState, 2).PadLeft(12, '0').Reversal().ToList();
                    if (Convert.ToInt32(bin_axis[0].ToString()) == 1)
                    {
                        //通知全局
                        BcFactory.Instance.RunState(RunEnum.急停);
                        BCAlertHelper.Log($"{item.Name}报警", LogLevel.严重);
                    }

                    m_Data.AxisState.Add(id, new AxisStatus()
                    {
                        报警 = Convert.ToInt32(bin_axis[0].ToString()),
                        正限位 = Convert.ToInt32(bin_axis[1].ToString()),
                        负限位 = Convert.ToInt32(bin_axis[2].ToString()),
                        原点 = Convert.ToInt32(bin_axis[4].ToString()),
                        使能 = dmc_read_sevon_pin(_bcId, id),
                        位置 = GetAxisPosition(id)
                    });
                    #endregion
                }
                PubSub.Hub.Default.PublishAsync(m_Data);
            }
            catch (Exception ex)
            {
                Log4.Error($"【板卡监控】{ex.Message}", ex);
            }
        }
        private void Error(short errId)
        {
            if (errId != 0)
            {
                throw new Exception($"错误代码【{errId}】{GetErrorMsg[errId]}");
            }
        }
        private void ErrorByEthernet(short errId)
        {
            if (errId != 0)
            {
                throw new Exception($"总线错误码【{errId}】{GetErrorMsgByEthernet[errId]}");
            }
        }

        List<int> IBoardCard.GetIn()
        {
            throw new NotImplementedException();
        }

        List<int> IBoardCard.GetOut()
        {
            throw new NotImplementedException();
        }

        private Dictionary<short, string> GetErrorMsgByEthernet = new Dictionary<short, string>()
        {
           //总线错误码
          {0x0009,"同步时钟丢失，第一个从站丢失"},
          {0x000E,"总线初始化不成功，总线未连接"},
          {0x0010,"总线初始化连接超时"},
          {0x0013,"SDO操作失败"},
          {0x0014,"无效的SDO指令"},
          {0x001E,"从站丢失"},
          {0x001F,"读取配置文件错误，xml文件有问题"},
          {0x0020,"总线无法切换到op状态，总线连接有问题,可能的原因是总线没有下载配置文件"},
          {0x0022,"从站的状态切换寄存器与其配置的xml不匹配，导致读写从站寄存器失败"},
          {0x0024,"从站错误，可能的原因是从站无法切换状态机，查找从站错误码信息,即读取0x603F地址"},
          {0x0026,"总线网络连接有问题，可能网线有干扰，导致丢数据包"},
          {0x0027,"同步时钟丢失，网络时钟不稳定，1.该现象可能在总线连接过程中出现，可能运动中程序负载太大导致，可增加总线周期调试；2.网络干扰大导致"},
          {0x002A,"从站无法切换到OP状态"},
          {0x002D,"网络连接线已连接"},
          {0x0031,"从站不支持SDO操作"},
          {0x0041,"读写SDO超时"},
          {0x0047,"该地址不支持SDO操作"},
          {0x0048,"该地址不可读，只能写操作"},
          {0x0049,"该地址不可写，只能读操作"},
          {0x004A,"对象在对象字典中不存在"},
          {0x004B,"不能映射为PDO对象"},
          {0x017B,"网线断开,可能网线插错，入口与出口不匹配"},
          {0x01C2,"总线的时钟发生较大的跳动，可能总线周期太小导致"},
          {0x0206,"SDO写操作失败"},
          {0x0207,"SDO读操作失败"},
          {0x020C,"从站有报警出现，需求查找具体的从站错误码地址0x603F"},
          {0x020D,"从站地址无法收到数据，可能掉线等"},
          {0x0224,"网络掉线，或者新加入了从站，该从站没有进入OP状态"},
          {0x0225,"网络接线重新连上"},
          {0x0226,"网络掉线，或者没有连接网线"},
          {0x0227,"从站掉线"},
          {0x0229,"从站状态状态错误，从站AL-Status寄存器错误，可能网络中网线被拔出后又插上"},
          {0x022B,"无法连接从站地址"},
        };
        private Dictionary<short, string> GetErrorMsg = new Dictionary<short, string>()
        {
            //函数返回值错误码
            { 1,"总线初始化不成功"},
            { 2,"参数错误"},
            { 3,"通讯超时"},
            { 4,"控制器忙、控制器相应轴处于运动中"},
            { 5,"链接太频繁"},
            { 8,"网络链接失败，请查看连线及通讯参数"},
            { 9,"句柄错误，网络未链接或链接已断开"},
            { 10,"发送失败，网络未链接或链接已断开"},
            { 12,"固件文件错误"},
            { 14,"固件不匹配"},
            { 17,"不支持的功能"},
            {20,"固件参数错误"},
            {22,"固件当前状态不允许操作"},
            {24,"固件不支持的功能"},
            {25,"密码错误"},
            {26,"密码错误输入次数受限"},
            {30,"手轮脉冲的轴档位选择超出范围（软件控制模式）"},
            {31,"手轮脉冲的轴映射数量超出范围"},
            {32,"手轮脉冲的倍率档位选择超出范围（软件控制模式）"},
            {33,"已进入手轮脉冲模式，不能切换软硬件控制模式"},
            {34,"轴已在运动，不能切换到手轮模式"},
            {50,"LIST号超出范围"},
            {51,"LIST没有初始化"},
            {52,"参数不在有效范围"},
            {53,"LIST已经打开"},
            {54,"LIST没有初始化"},
            {55,"轴数不在有效范围"},
            {56,"轴映射表为空"},
            {57,"映射轴错误"},
            {58,"映射轴忙"},
            {59,"运动中不允许更改参数"},
            {60,"缓冲区已满"},
            {61,"半径为0或小于两点的距离的一半"},
            {62,"LIST已经启动"},
            {63,"加减速时间为0"},
            {64,"主要LIST没有启动"},
            {67,"圆弧插补在半径模式下起点和终点不能重合"},
            {70,"S曲线加减速模式，平滑时间为零出错"},
            {71,"起跳速度小于零"},
            {72,"最大速度小于等于零"},
            {73,"终点速度小于零"},
            {74,"规划长度小于等于零"},
            {75,"最小匀速时间小于零"},
            {76,"规划模式非T型非S型"},
            {77,"加速时间等于零"},
            {78,"减速时间等于零"},
            {79,"规划长度小于等于零（速度规划函数返回，74为长度计算时返回）"},
            {80,"s时间设置错误(小于等于0)"},
            {81,"起始速度绝对值设置错误(小于0)"},
            {82,"最大速度绝对值设置错误(小于等于0)"},
            {83,"停止速度绝对值设置错误(小于0)"},
            {84,"运动距离为0，无法运动"},
            {101,"所选轴超出最大值"},
            {102,"轴正在运动，不能设置参数"},
            {103,"轴正在运动，不能进入该模式"},
            {104,"轴处于正限位，不能正向运动"},
            {105,"轴处于负限位，不能负向运动"},
            {106,"轴处于软正限位，不能正向运动"},
            {107,"轴处于软负限位，不能负向运动"},
            {108,"轴处于非点位模式，不能强制变位"},
            {109,"设置最大速度错误，不能为0"},
            {110,"设置轴当量错误，不能为0"},
            {111,"设置反向间隙错误，不能为负值"},
            {112,"设置位置错误，已超出允许范围"},
            {117,"设置轴处于未使能状态"},
            {118,"设置轴非总线轴，不能进行该总线操作"},
            {121,"所选比较轴超出范围"},
            {122,"比较点数已满，不能继续添加"},
            {123,"进行比较的IO超出范围"},
            {124,"选择的高速比较IO超出范围"},
            {130,"映射的轴超出范围"},
            {140,"所选轴超出范围"},
            {141,"控制点已满，不能继续添加"},
            {142,"控制点已满，不能继续添加"},
            {143,"插入段时间为0或者负数"},
            {200,"所选轴超出最大值"},
            {202,"设置的最大速度为0"},
            {203,"设置的加速度小于等于0"},
            {207,"同时处于正、负限位,无法启动回零运动"},
            {210,"TRACE功能已经启动，请停止后再次启动"},
            {258,"通讯超时，检查接线及通讯参数配置"},
            {10000+1,"超过轴个数限制"},
            {10000+3,"地址不存在"},
            {10000+4,"轴不存在"},
            {10000+5,"设置的轴号不存在"},
            {10000+6,"IO点不存在"},
            {10000+8,"设置的从站类型不存在"},
            {10000+9,"无效EtherCAT参数"},
            {10000+11,"无效SDO参数"},
            {10000+12,"无效主站"},
            {10000+13,"配置文件不存在"},
            {10000+15,"超过EtherCAT从站个数限制"},
            {10000+16,"设置的主站类型错误"},
            {10000+17,"映射文件不存在"},
            {10000+18,"配置文件为空"},
            {10000+19,"配置文件格式错误"},
            {10000+20,"轴及IO映射错误"},
            {10000+21,"下载的配置文件错误"},
            {10000+22,"轴运行模式设置错误"},
            {10000+23,"总线类型错误"},
            {10000+24,"PP模式下轴在运动中"},
            {10000+25,"参数错误"}
        };

        #endregion
    }
}